package com.ruoyi.bizsys.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.bizsys.domain.*;
import com.ruoyi.bizsys.mapper.ApplyContactsMapper;
import com.ruoyi.bizsys.mapper.CustContactsRelativeMapper;
import com.ruoyi.bizsys.mapper.DeviceContactsMapper;
import com.ruoyi.bizsys.service.*;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.Func;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
 * 通讯录授权Service业务层处理
 *
 * @author african-loan
 * @date 2021-10-28
 */
@Slf4j
@Service
public class ApplyContactsServiceImpl extends ServiceImpl<ApplyContactsMapper, ApplyContacts> implements IApplyContactsService {

    @Autowired
    ApplyContactsMapper applyContactsMapper;

    @Autowired
    CustContactsRelativeMapper custContactsRelativeMapper;

    @Autowired
    RedisCache redisCache;

    @Autowired
    ISysConfigService iSysConfigService;

    @Autowired
    DeviceContactsMapper deviceContactsMapper;

    @Autowired
    ICustContactsRelativeService iCustContactsRelativeService;

    @Autowired
    ICustContactsSerialnoService iCustContactsSerialnoService;

    @Autowired
    IAppDeviceInfoService iAppDeviceInfoService;

    @Override
    public JSONArray getByCustNoAndApplyNo(String custNo, String applyNo, String tableName, List<DeviceContactsRelative> tableNames) {

        if (StringUtils.isNotBlank(tableName)) {
            List<ApplyContacts> byCustNoAndApplyNo = applyContactsMapper.getByCustNoAndApplyNo(custNo, applyNo, tableName);
            return JSONArray.parseArray(JSON.toJSONString(byCustNoAndApplyNo));
        } else {
            JSONArray jSONArray = new JSONArray();
            for (int i = 0; i < tableNames.size(); i++) {
                List<DeviceContacts> byDeviceIdAndApplyNo = deviceContactsMapper.getByDeviceIdAndApplyNo(tableNames.get(i).getDeviceId(), applyNo, tableNames.get(i).getContactsTableName());
                jSONArray.addAll(JSONArray.parseArray(JSON.toJSONString(byDeviceIdAndApplyNo)));
            }
            return jSONArray;
        }
    }

    @Override
    public int selectContactsCount(String userId, String applyNo, String tableName) {
        return applyContactsMapper.selectContactsCount(userId, applyNo, tableName);
    }

    @Override
    public Integer batchSaveContactsTableName(List<ApplyContacts> contactsList, String tableName) {
        return applyContactsMapper.batchSaveContacts(contactsList, tableName);
    }

    @Override
    public String getTableName(String custNo) {
        QueryWrapper<CustContactsRelative> applyContactsQueryWrapper = new QueryWrapper<>();
        applyContactsQueryWrapper.eq("cust_no", custNo).last("limit 1");
        CustContactsRelative one = custContactsRelativeMapper.selectOne(applyContactsQueryWrapper);
//        String tableName;
//        if(one==null || StringUtils.isBlank(one.getContactsTableName())){
//            //获得最新的表名
//            tableName = getNewTableName();
//            CustContactsRelative custContactsRelative = new  CustContactsRelative();
//            custContactsRelative.setCustNo(custNo);
//            custContactsRelative.setContactsTableName(tableName);
//            iCustContactsRelativeService.insertCustContactsRelative(custContactsRelative);
//        }else{
//            tableName = one.getContactsTableName();
//        }
        return one != null ? one.getContactsTableName() : "";
    }

    @Override
    public String getNewTableName() {

        String applyContactsNewTable = redisCache.getCacheObject(Constants.APPLY_CONTACTS_NEW_TABLE);

        if (StringUtils.isNotBlank(applyContactsNewTable)) {
            return applyContactsNewTable;
        } else {
            String newTableName = custContactsRelativeMapper.getNewTableName();
            redisCache.setCacheObject(Constants.APPLY_CONTACTS_NEW_TABLE, newTableName);
            return newTableName;
        }
    }

    public Integer getNewTableNumber() {
        String newTableName = getNewTableName();
        String[] s = newTableName.split("_");
        return Integer.parseInt(s[s.length - 1]);
    }

    @Override
    public void checkNewTableData() {
        Integer cust_contact_split_nums = Integer.parseInt(iSysConfigService.selectConfigByKey("cust_contact_split_nums"));

        Integer newTableNumber = getNewTableNumber();
        Integer count = applyContactsMapper.getCount(Constants.CONTACTS_TABLE_NAME + newTableNumber);

        if (count >= cust_contact_split_nums) {

            String tableName = Constants.CONTACTS_TABLE_NAME + (newTableNumber + 1);
            applyContactsMapper.createTable(tableName);
            redisCache.setCacheObject(Constants.APPLY_CONTACTS_NEW_TABLE, tableName);
        }

    }

    @Override
    public void clearData() {
        log.info("clearData==============进来了");
        //将所有表都取出来
        Integer newTableNumber = getNewTableNumber();

        for (int i = newTableNumber; i >= 1; i--) {

            //拿到所有需要更新的数据
            String tableName = Constants.CONTACTS_TABLE_NAME + i;
            //临时修改长度
            applyContactsMapper.updateGroupConcatMaxLen();
            List<ApplyContacts> list = applyContactsMapper.getClearData(tableName);

            //循环所有用户
            for (int j = 0; j < list.size(); j++) {
                ApplyContacts applyContacts = list.get(j);
                try {
                    clearDataByIds(tableName, applyContacts.getApplyNo());
                } catch (Exception e) {
                    log.error("清理数据异常，id：{}", applyContacts.getApplyNo().split(",")[0], e);
                }
            }
        }

    }

    /**
     * 对某个用户的数据进行去重
     *
     * @param tableName
     * @param ids       需要操作的通讯录ids
     */
    @Override
    @Transactional
    public void clearDataByIds(String tableName, String ids) {

        List<String> idList = new ArrayList<>(Arrays.asList(ids.split(",")));

        //没用到的id（重复id）
        List<String> noUseIdList = new ArrayList<>();
        List<String> useList = new ArrayList<>(Arrays.asList(ids.split(",")));

        List<ApplyContacts> list = applyContactsMapper.getByIds(tableName, idList);
        //合并数据
        Map<CustContactsSerialno, String> map = new HashMap<>();
        Map<ApplyContacts, String> map1 = new HashMap<>();

        for (int i = 0; i < list.size(); i++) {

            ApplyContacts applyContacts = list.get(i);

            ApplyContacts applyContactsMap = new ApplyContacts();
            applyContactsMap.setCallName(applyContacts.getCallName());
            applyContactsMap.setCustNo(applyContacts.getCustNo());
            applyContactsMap.setPhone(applyContacts.getPhone());


            CustContactsSerialno custContactsSerialno = new CustContactsSerialno();
            custContactsSerialno.setApplyNo(applyContacts.getApplyNo());
            custContactsSerialno.setActionType(applyContacts.getActionType());
            custContactsSerialno.setCustNo(applyContacts.getCustNo());
            custContactsSerialno.setCreateTime(applyContacts.getCreateTime());


            if (map1.get(applyContactsMap) != null) {
                noUseIdList.add(list.get(i).getId() + "");
                map.merge(custContactsSerialno, map1.get(applyContactsMap), (oldValue, newValue) -> oldValue + "," + newValue);
            } else {
                map1.put(applyContactsMap, list.get(i).getId() + "");
                map.merge(custContactsSerialno, applyContacts.getId() + "", (oldValue, newValue) -> oldValue + "," + newValue);
            }
        }

        useList.removeAll(noUseIdList);

        for (CustContactsSerialno key : map.keySet()) {
            String value = map.get(key);
            Set set = new HashSet(Arrays.asList(value.split(",")));
            map.put(key, set.toString().trim().replace("[", "").replace("]", ""));
        }
        //插入
        iCustContactsSerialnoService.batchSave(map);

        //修改已用到数据
        applyContactsMapper.updateApplyNo(tableName, useList);
        //删除未用到数据
        if (noUseIdList.size() > 0) {
            applyContactsMapper.deleteByIds(tableName, noUseIdList);
        }

    }

    @Override
    public int getCntContactsNum(String tableName, String custNo, String applyNo) {
        return applyContactsMapper.getCntContactsNum(tableName, applyNo, custNo);
    }

    @Override
    public int familycontactInContact(String tableName, List<DeviceContactsRelative> tableNames, String custNo, String contactPhone, String contactPhone2) {

        if (StringUtils.isBlank(contactPhone) && StringUtils.isBlank(contactPhone2)) {
            return -1;
        }
        int matches = 0;
        //留后10位
        if (Func.isNotEmpty(contactPhone)) {
            contactPhone = StringUtils.substringAfter(contactPhone, 10);
            if (checkFamilycontactInContact(tableName, tableNames, custNo, contactPhone)) {
                matches++;
            }
        }
        if (Func.isNotEmpty(contactPhone2)) {
            contactPhone2 = StringUtils.substringAfter(contactPhone2, 10);
            if (checkFamilycontactInContact(tableName, tableNames, custNo, contactPhone2)) {
                matches++;
            }

        }
        return matches;
    }

    public boolean checkFamilycontactInContact(String tableName, List<DeviceContactsRelative> tableNames, String custNo, String phone) {
        if (StringUtils.isNotBlank(tableName)) {
            return applyContactsMapper.familycontactInContact(tableName, custNo, phone) > 0;
        } else {
            int nums = 0;
            for (int i = 0; i < tableNames.size(); i++) {
                nums += deviceContactsMapper.familycontactInContact(tableNames.get(i).getContactsTableName(), tableNames.get(i).getDeviceId(), phone);
            }
            return nums > 0;
        }
    }

    @Override
    public String getAllcontacthaschina(List<DeviceContactsRelative> tableNames, String tableName, String custNo) {

        if (StringUtils.isNotBlank(tableName)) {
            return applyContactsMapper.getAllcontacthaschina(tableName, custNo);
        } else {
            for (int i = 0; i < tableNames.size(); i++) {
                String allcontacthaschina = deviceContactsMapper.getAllcontacthaschina(tableNames.get(i).getContactsTableName(), tableNames.get(i).getDeviceId());
                if (allcontacthaschina.equals("1")) {
                    return "1";
                }
            }
            return "0";
        }
    }

    @Override
    public String get7DaysContactsCount(String tableName, String custNo) {
        return baseMapper.get7DaysContactsCount(tableName, custNo);
    }

    @Override
    public void syncExcludePhone() {
        for (int i = getNewTableNumber(); i >= 1; i--) {
            //拿到所有需要更新的数据
            applyContactsMapper.syncExcludePhone(Constants.CONTACTS_TABLE_NAME + i);
        }
    }

    @Override
    public List<ApplyContacts> getCollectionPhone(String tableName, String userId, int size) {
        return applyContactsMapper.getCollectionPhone(tableName, userId, size);
    }

    public Map<CustContactsSerialno, String> mergeData(List<ApplyContacts> list) {

        Map<CustContactsSerialno, String> map = new HashMap<>();

        for (int i = 0; i < list.size(); i++) {
            ApplyContacts applyContacts = list.get(i);
            String[] split = applyContacts.getApplyNo().split(",");
            for (int j = 0; j < split.length; j++) {

                CustContactsSerialno custContactsSerialno = new CustContactsSerialno();
                custContactsSerialno.setApplyNo(split[j].split("-")[1]);
                custContactsSerialno.setActionType(split[j].split("-")[0]);
                custContactsSerialno.setCustNo(applyContacts.getCustNo());
                custContactsSerialno.setCreateTime(applyContacts.getCreateTime());

                map.merge(custContactsSerialno, applyContacts.getId() + "", (oldValue, newValue) -> oldValue + "," + newValue);
            }
        }
        return map;
    }

}
